package com.atguigu.gmall.activity.config;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.activity.pojo.UserRecode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/***
 * 设置rabbit的消息可靠性投递
 */
@Component
public class SeckillRabbitTemplateConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 初始化确认模式和返回模式
     */
    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this::confirm);
        rabbitTemplate.setReturnCallback(this::returnedMessage);
    }

    /**
     * 确认模式
     *
     * @param correlationData
     * @param b
     * @param s
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        if (!b) {
            //消息未进入交换机
            //获取消息对象
            Message message = correlationData.getReturnedMessage();
            //异常处理
            this.messageSendFail(message);
        }
    }

    /**
     * 返回模式
     *
     * @param message
     * @param i
     * @param s
     * @param s1
     * @param s2
     */
    @Override
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
        //消息进入交换机，未进入队列
        //异常处理
        this.messageSendFail(message);
    }

    /**
     * 消息投递失败的处理
     *
     * @param message
     */
    private void messageSendFail(Message message) {
        //获取消息内容
        String messageJsonString = new String(message.getBody());
        //反序列化
        UserRecode userRecode = JSONObject.parseObject(messageJsonString, UserRecode.class);
        //更改用户的排队状态
        userRecode.setStatus(3);
        userRecode.setMsg("服务器发生异常,排队失败!");
        //存入redis中
        redisTemplate.opsForValue().set("user_recode_" + userRecode.getUsername(), userRecode);
        //消息发送异常，删除控制重复排队的key
        redisTemplate.delete("user_queue_count_" + userRecode.getUsername());
    }
}
